package com.ttbj.product.yitong.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ttbj.api.dto.Page;
import com.ttbj.api.dto.YtPayDto;
import com.ttbj.api.exception.BusinessException;
import com.ttbj.api.yitong.YtPayService;
import com.ttbj.core.util.DateUtils;
import com.ttbj.core.util.DtoTransitionUtils;
import com.ttbj.product.util.PropertiesUtil;
import com.ttbj.product.ytpayutil.HttpClient;
import com.ttbj.product.ytpayutil.MD5;
import com.ttbj.product.ytpayutil.RandomCharData;
import com.ttbj.product.ytpayutil.UtilBase64;
import com.ttbj.ytpay.dao.YtPayMapper;


@Service("ytPayService")
public class YtPayServiceImpl implements YtPayService{
	
	@Autowired
	private YtPayMapper ytPayMapper;
	
	
	private static final Logger logger = LoggerFactory.getLogger(YtPayServiceImpl.class);
	
	@Override
	public List<YtPayDto> findYtPayInfoByPage(String startDateTime, String endDateTime, String merOrderNum, String orderId, Page page)
			throws BusinessException {
		List<YtPayDto> ytPayDtos = this.ytPayMapper.queryYtPayInfoByPage(startDateTime, endDateTime, merOrderNum, orderId, page);
		return ytPayDtos;
	}

	@Override
	public Integer findYtPayInfoByPageCount(String startDateTime, String endDateTime, String merOrderNum, String orderId)
			throws BusinessException {
		Integer count = this.ytPayMapper.queryYtPayInfoByPageCount(startDateTime, endDateTime, merOrderNum, orderId);
		return count;
	}

	@Override
	public Integer addToPaymentRecord(Object object) {
		YtPayDto ytPayDto = null;
		int i = 0;
		if (null != object) {
			logger.info("传来的对象：{}", object.toString());
			ytPayDto = (YtPayDto) DtoTransitionUtils.trans(YtPayDto.class, object);
		}
		if (null != ytPayDto) {
			logger.info("支付完成后保存支付信息：{}", ytPayDto.toString());
			ytPayDto.setTranDateTime(DateUtils.getDateTimeStr(ytPayDto.getTranDateTime()));	//重新把交易时间格式化成 yyyy-MM-dd HH:mm:ss格式
			ytPayDto.setPayMentTime(DateUtils.getDateTimeStr(ytPayDto.getPayMentTime()));//重新把支付时间格式化成 yyyy-MM-dd HH:mm:ss格式
			ytPayDto.setSettleDate(DateUtils.getShortDateStr(ytPayDto.getSettleDate()));//重新把清算日格式化成 yyyy-MM-dd格式
			i = this.ytPayMapper.insertPaymentRecord(ytPayDto);
		}
		return i;
	}

	@Override
	public void transactionQueryAndUpdate(String merOrderNum, String tranDate, String respCode) {
		
	}

	@Override
	public Map<String, String> loadTradeFile(Integer type, String tranDate) throws Exception {
		Map<String, String> requestMap = new HashMap<>();
		if (type ==null || StringUtils.isBlank(tranDate)) {
			requestMap.put("respCode", "0001");
			requestMap.put("respMsg", "数据有错误，无法下载");
			return requestMap;
		}
		String merchantId = null;	//商户号
		String dataKey = null;	//dataKey
		if (type == 1) {
			merchantId = PropertiesUtil.getInstance().getValue("merchantId");
			dataKey = PropertiesUtil.getInstance().getValue("datakey");
		}else if (type == 2) {
			merchantId = PropertiesUtil.getInstance().getValue("wxSP_merchantId");
			dataKey = PropertiesUtil.getInstance().getValue("wxSP_datakey");
			logger.info("merchantId：{}，dataKey：{}", merchantId, dataKey);
		}else {
			requestMap.put("respCode", "0001");
			requestMap.put("respMsg", "请选择正确的支付方式");
			return requestMap;
		}
		//把时间格式中间的“-”去掉
		tranDate = tranDate.replaceAll("-", "");
		String txnString = merchantId + "|" + tranDate;	//签名字段
		String signValue = MD5.getInstance().getMD5ofStr(txnString + dataKey);	//签名进行加密
		requestMap.put("merchantId", merchantId);
		requestMap.put("tranDate", tranDate);
		requestMap.put("signValue", signValue);
		//对账文件下载地址
		String loadFileUrl = PropertiesUtil.getInstance().getValue("loadTradeFile_url");
		//HTTP连接，发送数据并获取返回的数据
		String result = new HttpClient(loadFileUrl, 6000, 6000).send(requestMap, "UTF-8");
		requestMap.clear();
		return requestMap = transStringToMap(result, "&", "=");	//响应的结果转换为map;
	}
	
	/**
     * 使用 Map按key进行排序得到key=value的字符串
     * @param mapString
     * @param separator K-V与K-V之间的拼接字符串  & 或者|...
     * @param pairSeparator K与V之间的拼接字符串 = 或者其他...
     * @return
     */
    public static Map<String, String> transStringToMap(String mapString, String separator, String pairSeparator) {
    	Map<String, String> map = new HashMap<String, String>();
    	String[] fSplit = mapString.split(separator);
    	for (int i = 0; i < fSplit.length; i++) {
	          if (fSplit[i]==null||fSplit[i].length()==0) {
	              continue;
	          }
	          String[] sSplit = fSplit[i].split(pairSeparator);
	          String value = fSplit[i].substring(fSplit[i].indexOf('=') + 1, fSplit[i].length());
	          map.put(sSplit[0], value);
         }
         return map;
     }

	@Override
	public Map<String, String> tkTransaction(String orgMerOrderNum, String refundAmtStr) throws Exception {
		//商户代码
		String merchantId = PropertiesUtil.getInstance().getValue("merchantId");
		//版本号
		String version = PropertiesUtil.getInstance().getValue("pay_version");
		//业务代码
		String bussId = PropertiesUtil.getInstance().getValue("bussId");
		//dataKey
		String dataKey = PropertiesUtil.getInstance().getValue("datakey");
		//退款的地址
		String tkURL = PropertiesUtil.getInstance().getValue("tk_url");
		//退款商户订单号，自定义的
		String merOrderNum = "TK" + DateUtils.getCurDtsStr() + RandomCharData.createData(8);
		//签名前拼接的字符串
		String txnString = version + "|" + merchantId + "|" + orgMerOrderNum + "|" + merOrderNum + "|" + refundAmtStr;
		//签名
		String signValue = MD5.getInstance().getMD5ofStr(txnString + dataKey);	//签名进行加密
		Map<String, String> requestMap = new HashMap<>();
		requestMap.put("merchantId", merchantId);
		requestMap.put("version", version);
		requestMap.put("orgMerOrderNum", orgMerOrderNum);
		requestMap.put("bussId", bussId);
		requestMap.put("merOrderNum", merOrderNum);
		requestMap.put("refundAmtStr", refundAmtStr);
		requestMap.put("signValue", signValue);
		//HTTP连接，发送数据并获取返回的数据
		String result = new HttpClient(tkURL, 6000, 6000).send(requestMap, "UTF-8");
		requestMap.clear();
		requestMap = transStringToMap(StringUtils.trim(result), "&", "=");	//响应的结果转换为map;
		//把响应报文里msg，通过base64解码后重新赋值
		requestMap.put("msg", new String(UtilBase64.decode(requestMap.get("msg")), "UTF-8"));
		//响应报文的验签，判断与返回的signValue是否一致，一致验签成功，否则报文不可信
		txnString = "merOrderNum=" + requestMap.get("merOrderNum") + "&orgMerOrderNum=" + requestMap.get("orgMerOrderNum")
					+ "&oTxnAmt=" + requestMap.get("oTxnAmt") + "&refAmt=" + requestMap.get("refAmt")
					+ "&refundAmtStr=" + requestMap.get("refundAmtStr") + "&respCode=" + requestMap.get("respCode") + "&";
		signValue = MD5.getInstance().getMD5ofStr(txnString + dataKey);	//签名进行加密
		//截取响应报文里的签名字符串
		String respSignValue = StringUtils.trim(result.substring(result.lastIndexOf("&") + 1));
		logger.info("返回的签名：{}，验签的签名：{}", respSignValue, signValue);
		//如果签名不一致，直接返回
		if (!signValue.equals(respSignValue)) {
			throw new Exception("报文被人篡改，请重试退款！");
		}
		return requestMap;
	}
}
